#ifndef __PROTOCOL_H__
#define __PROTOCOL_H__

#include "Marcos.h"
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <cstring>
#include <functional>
#include <map>
#include "Transmiter.h"
#include "spdlog/spdlog.h"

#include "PosConvert.h"

#include "Logger.h"

using namespace std;

// namespace NS_SDK{

#define HEAD_M  'M'
#define HEAD_E  'E'
#define HEAD_S1 'S'
#define HEAD_S2 'S'

#define TAIL_E 'E'
#define TAIL_N 'N'
#define TAIL_D 'D'



//固定的报文长度
#define FRAME_LEN_HEAD2LEN (12)
#define FRAME_LEN_CRC       (2)
#define FRAME_LEN_END       (3)
#define FRAME_TOTAL_WITHOUT_PAYLOAD (FRAME_LEN_HEAD2LEN+FRAME_LEN_CRC+FRAME_LEN_END)

//报文索引位置
#define IDX_HEAD_M  (0)
#define IDX_HEAD_E  (1)
#define IDX_HEAD_S1 (2)
#define IDX_HEAD_S2 (3)

#define IDX_TAIL_E(x)  (x+FRAME_LEN_HEAD2LEN+FRAME_LEN_CRC)   //其中x是数据payload的长度
#define IDX_TAIL_N(x)  (x+FRAME_LEN_HEAD2LEN+FRAME_LEN_CRC+1)  
#define IDX_TAIL_D(x)  (x+FRAME_LEN_HEAD2LEN+FRAME_LEN_CRC+2) 

#define IDX_CRC_H(x)  (x+FRAME_LEN_HEAD2LEN)    //CRC16 校验 高字节
#define IDX_CRC_L(x)  (x+FRAME_LEN_HEAD2LEN+1)  //CRC16 校验 低字节

#define IDX_VERSON  (4)   //协议版本号 索引
#define IDX_SERIAL  (5)   //序列号 索引
#define IDX_UPDOWN_TYPE    (9)    //报文类型 索引
#define IDX_PAYLOAD_LEN (10)   //数据长度索引
#define IDX_PAYLOAD_CMD  (12)     //数据包中指令索引
#define IDX_PAYLOAD_DATA  (13)     //数据包首字节 索引



//控制指令定义
// #define CMD_START 1  //启动运行
// #define CMD_PAUSE 2  //暂停运行
// #define CMD_STOP  3   //停止运行
// #define CMD_PTS_MODE1 4  //下发点位 格式1
// #define CMD_PTS_MODE2 5  //下发点位 格式2
// #define CMD_SET_DEFAULT_SPD 6   //设置点击默认速度
// #define CMD_GET_DEFAULT_SPD 7  //获取电机默认速度
// #define CMD_CTRL_AIX        8   //控制单轴移动
// #define CMD_MAX			    9

// //上行报文
// #define CMD_ACK  	      (0x80)   //应答报文
// #define CMD_FB_INFO       (101)    //反馈实时信息
// #define CMD_ORIGIN_ENC    (102)    //反馈实时信息

#define CMD_ACK_LEN_PAYLOAD (7)
#define CMD_FB_INFO_LEN_PAYLOAD (77)
#define CMD_ORIGIN_ENC_LEN_PAYLOAD (25)


using callback_func_ptr = void (*)(int total, int index, int trigger_number,tpDNRouteStruct route);

//错误码回调函数
using callback_errcode_func_ptr = void (*)(uint16_t err_code1,uint16_t err_code2,uint16_t err_code3,uint16_t err_code4,uint16_t err_code5,uint16_t err_code6);

class Proto {

typedef enum : uint8_t{
    TYPE_UP_STREAM = 1,  //上行数据
    TYPE_DOWN_STREAM  //下行数据
}UPDOWN_T;

typedef enum : uint8_t{
    IDX_PAYLOAD = 12,
}FRAME_IDX_T;

//---下行指令----
typedef enum : uint8_t{
    CMD_START = 1,  //启动运行
    CMD_PAUSE,  //暂停运行
    CMD_STOP,   //停止运行
    CMD_PTS_MODE1,  //下发点位 格式1
    CMD_PTS_MODE2,  //下发点位 格式2
    CMD_SET_DEFAULT_SPD,  //设置点击默认速度
    CMD_GET_DEFAULT_SPD,  //获取电机默认速度
    CMD_CTRL_AIX,  //控制单轴移动
    CMD_GET_RT_INFOS,  //获取实时信息
    CMD_SET_DO_OUTPUT,  //设置DO输出
    CMD_MAX,
}FRAME_CMD_DOWN_STREAM_T;

//-----上行指令-----
typedef enum : uint8_t{
    CMD_ACK = 0x80,  //启动运行
    CMD_DRV_ENABLE_FIN = 100,  //上传驱动器使能状态
    CMD_FB_INFO = 101,  //上传实时信息
    CMD_ORIGIN_ENC = 102,   //上传编码器原点
    CMD_MOTION_FIN = 103,  //运动完成
    CMD_SET_DEFAULT_SPD_FIN  =   104,   //默认速度设置完成
    CMD_GET_DEFAULT_SPD_FIN  =   105,   //默认速度获取完成
    CMD_SINGLE_AIX_FIN      = 106, //单轴控制完成
    CMD_ERR_CODE            =107    //故障信息
}FRAME_CMD_UP_STREAM_T;

public:
    Proto(TcpSocket & sock):
    serial_num(0),
    running_snd_frame(true),
    tcp_socket_(sock),
    flag_new_route(false),
    running_parse(true),
    thread_parse(&Proto::parse_loop, this),
    thread_snd_frame(&Proto::Send_RoutePts_Loop, this),
    logger_(LogMan::instance())
    {
        //添加解析函数
        Add_ParseFunc(CMD_ACK, std::bind(&Proto::Parse_Ack,this,std::placeholders::_1,std::placeholders::_2));
        Add_ParseFunc(CMD_FB_INFO, std::bind(&Proto::Parse_RealTime,this,std::placeholders::_1,std::placeholders::_2));
        Add_ParseFunc(CMD_ORIGIN_ENC, std::bind(&Proto::Parse_OriginPt_Enc,this,std::placeholders::_1,std::placeholders::_2));
        Add_ParseFunc(CMD_DRV_ENABLE_FIN, std::bind(&Proto::Parse_Drv_Enable_Stat,this,std::placeholders::_1,std::placeholders::_2));
        Add_ParseFunc(CMD_SET_DEFAULT_SPD_FIN, std::bind(&Proto::Parse_Set_Default_Spd_Fin,this,std::placeholders::_1,std::placeholders::_2));
        Add_ParseFunc(CMD_GET_DEFAULT_SPD_FIN, std::bind(&Proto::Parse_Get_Default_Spd_Fin,this,std::placeholders::_1,std::placeholders::_2));
        Add_ParseFunc(CMD_MOTION_FIN, std::bind(&Proto::Parse_Motion_Fin,this,std::placeholders::_1,std::placeholders::_2));
        Add_ParseFunc(CMD_SINGLE_AIX_FIN, std::bind(&Proto::Parse_SingleAix_Fin,this,std::placeholders::_1,std::placeholders::_2));
        Add_ParseFunc(CMD_ERR_CODE, std::bind(&Proto::Parse_Motor_Err,this,std::placeholders::_1,std::placeholders::_2));
        
        logger_->trace("Class Proto construct succ~~ ");
    }

    virtual ~Proto() {
        running_snd_frame = false;
        flag_new_route = false;
        running_parse = false;

        cv_pts_snd.notify_all(); // 唤醒可能阻塞的线程
        if (thread_snd_frame.joinable()) 
        {
            thread_snd_frame.join();
        }
        if (thread_parse.joinable()) 
        {
            thread_parse.join();
        }

        if (logger_) {
            logger_->flush(); // 显式刷新缓冲区
        }

    }

    // void Set_Socket(std::unique_ptr<TcpSocket> sock_ptr)
    // {
    //     tcp_socket_ = std::move(sock_ptr);
    // }

    TcpSocket::SocketType create_and_listen_socket(int port) 
    {
        return tcp_socket_.create_and_listen_socket(port);
    }

    bool create_connect_to_server(int port) 
    {
        return tcp_socket_.create_connect_to_server(port);
    }

    bool Is_Socket_Connected() const
    {
        return tcp_socket_.Is_Socket_Connected();
    }

    //--DBG----虚拟点位发送---
    bool DBG_Virtual_Pts_Set_20000_WaitFin();
    bool DBG_Virtual_Pts_Set_20000();
    bool DBG_Virtual_Pts_Set_0();

    //设置路径点位
    bool SetRoutePts(std::vector<tpDNRouteStruct> const & pos_routes,uint32_t num_pts,bool is_wait_run_fin);

    //应答事件
    void Event_Get_Ack();

    //获取"读取/设置默认速度"的应答
    void Event_Ack_GetSetSpd();

    //获取实时信息应答
    void Event_Get_Rt_Infos();

    //单个轴控制运动完成
    void Event_Get_SingleAix_Fin(uint8_t id,uint8_t stat);  

    //发送路径点线程
    bool Send_RoutePts_Loop();


    //启动运行
    bool Cmd_StartRun(uint16_t delay_trigger);
    //暂停运行
    bool Cmd_PauseRun();
    //继续运行
    bool Cmd_ResumeRun();
    //停止运行
    bool Cmd_StopRun();
    //获取实时信息
    bool Cmd_Get_RT_Infos();

    //设置默认速度
    bool Cmd_Set_Default_Spd(uint8_t id,float spd, bool * succ);
    //获取默认速度
    bool Cmd_Get_Default_Spd(uint8_t id,float * spd,bool * succ);
    //控制单个轴运动
    bool Cmd_Move_Sigle_Axis(uint8_t id,float pos,float spd);

    //获取设备位置信息
    bool Cmd_Get_Dev_Pos(tpDNPositionStruct & pos);
    //获取当前路劲点信息
    bool Cmd_Get_CurPts_Infos(int & index, tpDNRouteStruct & route);

    //设置DO 输出
    bool Cmd_DO_Ctrl(uint8_t id,uint8_t on_off);

    //设置坐标原点
    int SetOrigin(int index, tpDNOriginEncoderStruct & encoder);

    //加载坐标原点
    int LoadOrigin();

    //获取坐标原点的编码器值
    int GetOriginEncoder(tpDNOriginEncoderStruct & encoder);

    //判断是否所有驱动器使能成功
    bool Is_All_Drv_Enable() const
    { return is_all_drv_enable;}

    //判断是否运动任务结束
    bool Is_Motion_Fin();

    //设置回调函数
    void SetCallback(callback_func_ptr callback) 
    {
        cb_func = callback;
        logger_->debug("set callback function suncc !");
    }

    void SetCallback_Motor_Error(callback_errcode_func_ptr callback) 
    {
        cb_func_errcode = callback;
        logger_->debug("set callback Motor Err function suncc !");
    }

    //从第n个点开始组件报文，将连续num_pts个点组包,合成一个payload包
    uint32_t Make_Pts_Mode1_PayloadFrame(uint32_t start_idx,uint32_t num_pts); 

    //将payload包组成一个完整的包（加入帧头，尾。校验等）
    uint32_t MakeTotalFrame(UPDOWN_T updown,uint8_t * payload,uint16_t len_payload);

    //将当前报文尝试重发
    bool Retry_FrameSnd();

    //发送线程
    bool SendFrameLoop();

    //将底层报文发送到socket
    bool Send_Frame_To_Sock(uint16_t len);

    //判断是否运动任务结束
    // bool Is_Motion_Fin() const
    // { return is_drv_motion_fin; }

    // //判断是否运动任务结束
    // bool Is_Motion_Fin() const
    // { return is_pts_running == false; }

    // 计算数据块的CRC16值
    uint16_t Crc16_Calc(uint8_t* data, size_t length) 
    {
        uint8_t crc_hi = 0xFF;  // 高字节初始值
        uint8_t crc_lo = 0xFF;  // 低字节初始值
        
        for (size_t i = 0; i < length; ++i) {
            uint8_t index = crc_lo ^ data[i];
            crc_lo = crc_hi ^ auchCRCHi[index];
            crc_hi = auchCRCLo[index];
        }
        
        return (static_cast<uint16_t>(crc_lo) << 8) | crc_hi;
    }

    /*
    void print_buffer() { // 调试用
        std::lock_guard<std::mutex> lock(mutex_);
        std::cout << "Parse Buffer: ";
        for (int i = 0; i < buffer_index_; ++i) {
            std::cout << large_buffer_[i];
        }
        std::cout << std::endl;
    }
    */


    // //------原点和位置换算-----------------S
    
    // int Save_Ori_Pts()   //保存原点坐标
    // {
    //     return _pc.Save_Ori_Pts();
    // }

    // int Load_Ori_Pts()   //加载原点坐标
    // {
    //     return _pc.Load_Ori_Pts();
    // }

    // //------原点和位置换算-----------------E

private:

// CRC高位字节值表
    static constexpr uint8_t auchCRCHi[256] = {
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
        0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
        0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
        0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
        0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
        0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
        0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
        0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
        0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
        0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
        0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
    };

    // CRC低位字节值表
    static constexpr uint8_t auchCRCLo[256] = {
        0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
        0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
        0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
        0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
        0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
        0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
        0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
        0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
        0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
        0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
        0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
        0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
        0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
        0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
        0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
        0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
        0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
        0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
        0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
        0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
        0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
        0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
        0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
        0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
        0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
        0x43, 0x83, 0x41, 0x81, 0x80, 0x40
    };

    static constexpr uint32_t LEN_LARGE_BUFFER = 2048;
    static constexpr uint32_t LEN_MAX_PAYLOAD_BUFFER = 128;
    static constexpr uint32_t MIN_FRAME_LEN = 19;
    static constexpr uint8_t NUM_MOTOR = 6;


    //发送报文缓冲区
    static constexpr uint32_t LEN_BUFF_SND = 1200;
    uint8_t payload_buff[LEN_BUFF_SND];
    uint8_t frame_buff[LEN_BUFF_SND];

    // -----------路径点触发发送相关
    std::mutex mutex_pts_snd;
    std::condition_variable cv_pts_snd;

    //-------路径点发送相关------------
    std::mutex mutex_pts_snd_finish;
    std::condition_variable cv_pts_snd_finsh;
    bool is_pts_snd_timeout = false;
    bool is_pts_snd_finish = false;  

    //------点位执行完成----------
    std::mutex mutex_pts_run_finish;
    std::condition_variable cv_pts_run_finsh;

    //-------发送流程互斥相关---------
    std::mutex mutex_snd_process;  //发送流程互斥锁

    std::thread thread_snd_frame;
    bool running_snd_frame;
    bool flag_new_route;
    uint32_t pts_idx;  //当前待发送的路径点索引
    uint32_t pts_num_snd;  //当前待发送的点的数量
    uint32_t pts_num_total;  //路径内总共的点数

    std::mutex mutex_snd2socks;  //发送到底层socket

    // ---------------应答相关--------------
    std::mutex mutex_ack;
    std::condition_variable cv_ack;
    std::thread thread_ack_frame;
    bool flag_new_ack;

    //-----------速度 设置/获取 相关 -----------
    std::mutex mutex_ack_spd;
    std::condition_variable cv_ack_spd;
    bool flag_new_spd_ack;

    //-----------读取实时信息相关 相关 -----------
    std::mutex mutex_rt_infos;
    std::condition_variable cv_rt_infos;
    bool flag_rt_infos_ack;

    //-----------单轴运动相关  -----------
    std::mutex mutex_single[NUM_MOTOR];
    std::condition_variable cv_single[NUM_MOTOR];
    bool flag_sigle_ack[NUM_MOTOR] = {false,false,false,false,false,false};
    bool flag_sigle_stat[NUM_MOTOR] = {false,false,false,false,false,false};

    // //-----------DO控制相关  -----------
    // std::mutex mutex_do;
    // std::condition_variable cv_do;
    // bool flag_do_ack;
    

    //存储路径点原始数据 (单位：mm ,degree)
    std::shared_ptr<std::vector<tpDNRouteStruct>> route_origin;

    //存储路径点数据 (单位：编码器值), 用途：用于转换成编码器单位，下发至控制板
    std::shared_ptr<std::vector<tpDNRouteStruct_Enc>> route_pts;

    uint32_t board_remain_pts;  //控制板卡上剩余的控制点位（少于某个数量时，会再次触发下发）

    uint32_t serial_num;
    uint32_t serial_num_ack;

    static constexpr uint8_t FRAME_RETRY_SND = 20;
    static constexpr uint32_t NUM_PTS_2_SENT = 20;

    //--------Socket 相关------------------

    void parse_loop();
    
    bool Send_Process(uint8_t cmd,uint8_t * payload, uint32_t len_payload, bool need_ack);  //发送流程，包括了发送和等待应答

    // 添加无参无返回值的函数
    void Add_ParseFunc(int index, std::function<bool(uint8_t *,int)> func) 
    {
        func_parse[index] = func;
    }

    // 通过索引调用函数
    void Call_ParseFunc(int index,uint8_t* data,int len) 
    {
        if(index >= 0x80)  //应答报文
        {
            index &= 0x80;
        }
        if (auto it = func_parse.find(index); it != func_parse.end()) 
        {
            it->second(data,len);  // 执行解析函数
        } 
        else 
        {
            std::cerr << "Error: Function at index " << index << " not found!" << std::endl;
        }
    }

     // 判断缓冲区是否已满
    bool ParseBuff_Is_Full() const 
    {
        // return (buff_count == LEN_LARGE_BUFFER) || (((buff_in + 1) % LEN_LARGE_BUFFER) == buff_out);
        return (buff_count == LEN_LARGE_BUFFER);
    }
 
    // 判断缓冲区是否为空
    bool ParseBuff_Is_Empty() const 
    {
        return buff_count == 0;
    }
 
    // 获取剩余可用空间
    size_t ParseBuff_Available_Space() const 
    {
        return LEN_LARGE_BUFFER - buff_count;
    }



    //解析相关------------
    void Cpy_2_PayloadBuff(uint32_t idx, uint32_t len);

    bool Parse_Frame(uint8_t * data, uint32_t len);

    bool Parse_Ack(uint8_t * data, int len);  //解析应答

    bool Parse_RealTime(uint8_t * data, int len);  //解析实时值

    bool Parse_OriginPt_Enc(uint8_t * data, int len);  //解析原点编码器

    bool Parse_Drv_Enable_Stat(uint8_t * data, int len);  //解析驱动器使能状态

    bool Parse_Set_Default_Spd_Fin(uint8_t * data, int len); //解析设置默认速度

    bool Parse_Get_Default_Spd_Fin(uint8_t * data, int len); //解析获取默认速度

    bool Parse_Motion_Fin(uint8_t * data, int len);   //解析运动完成

    bool Parse_SingleAix_Fin(uint8_t * data, int len);  //单个轴控制完成

    bool Parse_Motor_Err(uint8_t * data, int len);  //电机故障解析

    void TriggerCallback(int total, int index, int trigger_number, tpDNRouteStruct route)  //回调函数
    {
        if(cb_func)  // 安全检查
        {  
            cb_func(total, index, trigger_number, route);
        }
        else
        {
            logger_->info(" this is Null function ptr ! ");
            std::cout<< " this is Null function ptr ! " <<std::endl;
        }
    }

    void MotorErrCallback(uint16_t *err)  //回调函数
    {
        if(cb_func_errcode)  // 安全检查
        {  
            cb_func_errcode(err[0], err[1], err[2], err[3], err[4], err[5]);
        }
        else
        {
            logger_->info(" MotorErrCallback : this is Null function ptr ! ");
            std::cout<< " MotorErrCallback : this is Null function ptr ! " <<std::endl;
        }
    }


    TcpSocket & tcp_socket_;
    // std::unique_ptr<TcpSocket> tcp_socket_;
    bool running_parse;
    
    uint8_t large_buffer_[LEN_LARGE_BUFFER] = {0};
    uint8_t payload_buffer_rx[LEN_MAX_PAYLOAD_BUFFER] = {0};
    uint32_t buff_in = 0;  //解析起始索引位置
    uint32_t buff_out = 0;  //解析起始索引位置
    uint32_t buff_count = 0;
    int buffer_index_ = 0;
    std::mutex mutex_largebuff;
    std::thread thread_parse;


    std::atomic<bool> is_all_drv_enable = false;   //伺服驱动器使能全部使能
    std::atomic<bool> is_drv_motion_fin = true;   //伺服驱动器是否运动结束

    bool is_set_default_spd_ok[NUM_MOTOR] = {false,false,false,false,false,false};   //是否成功设置默认速度
    bool is_get_default_spd_ok[NUM_MOTOR] = {false,false,false,false,false,false}; //是否成功获取默认速度
    
    int32_t spd_rt_enc[NUM_MOTOR] = {0,0,0,0,0,0};   //实时速度值 （编码器单位）
    int32_t pos_rt_enc[NUM_MOTOR] = {0,0,0,0,0,0};   //实时位置值 （编码器单位）
    int32_t abs_pos_rt_enc[NUM_MOTOR] = {0,0,0,0,0,0};   //实时绝对值编码器位置值 （编码器单位）

    uint32_t default_spd_Param[NUM_MOTOR] = {0,0,0,0,0,0};  //参数:默认速度
    uint16_t cur_pts_idx;   //当前路径点索引
    uint16_t cur_task_total_pts; //当前路径点任务总点数
    bool is_pts_running;  //是否路径点正在执行
    bool trigger_num = 0;   //Trigger 数量

    uint16_t motor_errcode[NUM_MOTOR]= {0,0,0,0,0,0};  //电机错误码 0x603F对象

    std::map<int, std::function<bool(uint8_t*,int)>> func_parse;  //解析函数数组

    //-------回调函数-----------------
    callback_func_ptr cb_func;
    callback_errcode_func_ptr cb_func_errcode;  //错误码回调函数

    //-----------原点和位置换算处理--------
    PosConvert _pc;
    
    std::shared_ptr<spdlog::logger> logger_;  // 日志器成员变量
};



// }

#endif




